Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


RNS/Interfaces/I2PInterface.py b051e76d00ab97baa948e69cdacadba3cf4739da (b051e76d) Text, 43.80 KB

T8b949e# Reticulum License
T8b949e#
T8b949e# Copyright (c) 2016-2025 Mark Qvist
T8b949e#
T8b949e# Permission is hereby granted, free of charge, to any person obtaining a copy
T8b949e# of this software and associated documentation files (the "Software"), to deal
T8b949e# in the Software without restriction, including without limitation the rights
T8b949e# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
T8b949e# copies of the Software, and to permit persons to whom the Software is
T8b949e# furnished to do so, subject to the following conditions:
T8b949e#
T8b949e# - The Software shall not be used in any kind of system which includes amongst
T8b949e# its functions the ability to purposefully do harm to human beings.
T8b949e#
T8b949e# - The Software shall not be used, directly or indirectly, in the creation of
T8b949e# an artificial intelligence, machine learning or language model training
T8b949e# dataset, including but not limited to any use that contributes to the
T8b949e# training or development of such a model or algorithm.
T8b949e#
T8b949e# - The above copyright notice and this permission notice shall be included in
T8b949e# all copies or substantial portions of the Software.
T8b949e#
T8b949e# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
T8b949e# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
T8b949e# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
T8b949e# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
T8b949e# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
T8b949e# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
T8b949e# SOFTWARE.

Tff7b72from T7ee787RNST7ee787.T7ee787InterfacesT7ee787.T7ee787Interface Tff7b72import Te6edf3Interface
Tff7b72import T7ee787socketserver
Tff7b72import T7ee787threading
Tff7b72import T7ee787platform
Tff7b72import T7ee787socket
Tff7b72import T7ee787time
Tff7b72import T7ee787sys
Tff7b72import T7ee787os
Tff7b72import T7ee787RNS
Tff7b72import T7ee787asyncio

Tff7b72class T56d364HDLCTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3FLAG Tff7b72= T79c0ff0x7E
Te6edf3ESC Tff7b72= T79c0ff0x7D
Te6edf3ESC_MASK Tff7b72= T79c0ff0x20

Tf0883e@staticmethod
Tff7b72def Td2a8ffescapeTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Te6edf3data Tff7b72= Te6edf3dataTff7b72.Td2a8ffreplaceTb4b4b4(Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3HDLCTff7b72.Td2a8ffESCTb4b4b4]Tb4b4b4)Tb4b4b4, Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3HDLCTff7b72.Td2a8ffESCTb4b4b4, Te6edf3HDLCTff7b72.Td2a8ffESCTff7b72^Te6edf3HDLCTff7b72.Td2a8ffESC_MASKTb4b4b4]Tb4b4b4)Tb4b4b4)
Te6edf3data Tff7b72= Te6edf3dataTff7b72.Td2a8ffreplaceTb4b4b4(Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3HDLCTff7b72.Td2a8ffFLAGTb4b4b4]Tb4b4b4)Tb4b4b4, Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3HDLCTff7b72.Td2a8ffESCTb4b4b4, Te6edf3HDLCTff7b72.Td2a8ffFLAGTff7b72^Te6edf3HDLCTff7b72.Td2a8ffESC_MASKTb4b4b4]Tb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3data

Tff7b72class T56d364KISSTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3FEND Tff7b72= T79c0ff0xC0
Te6edf3FESC Tff7b72= T79c0ff0xDB
Te6edf3TFEND Tff7b72= T79c0ff0xDC
Te6edf3TFESC Tff7b72= T79c0ff0xDD
Te6edf3CMD_DATA Tff7b72= T79c0ff0x00
Te6edf3CMD_UNKNOWN Tff7b72= T79c0ff0xFE

Tf0883e@staticmethod
Tff7b72def Td2a8ffescapeTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Te6edf3data Tff7b72= Te6edf3dataTff7b72.Td2a8ffreplaceTb4b4b4(Tffa657bytesTb4b4b4(Tb4b4b4[T79c0ff0xdbTb4b4b4]Tb4b4b4)Tb4b4b4, Tffa657bytesTb4b4b4(Tb4b4b4[T79c0ff0xdbTb4b4b4, T79c0ff0xddTb4b4b4]Tb4b4b4)Tb4b4b4)
Te6edf3data Tff7b72= Te6edf3dataTff7b72.Td2a8ffreplaceTb4b4b4(Tffa657bytesTb4b4b4(Tb4b4b4[T79c0ff0xc0Tb4b4b4]Tb4b4b4)Tb4b4b4, Tffa657bytesTb4b4b4(Tb4b4b4[T79c0ff0xdbTb4b4b4, T79c0ff0xdcTb4b4b4]Tb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3data

T8b949e# TODO: Neater shutdown of the event loop and
T8b949e# better error handling is needed. Sometimes
T8b949e# errors occur in I2P that leave tunnel setup
T8b949e# hanging indefinitely, and right now we have
T8b949e# no way of catching it. Sometimes the server
T8b949e# and client tasks are also not cancelled on
T8b949e# shutdown, which leads to errors dumped to
T8b949e# the console. This should also be remedied.

Tff7b72class T56d364I2PControllerTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3rns_storagepathTb4b4b4)Tb4b4b4:
Tff7b72import T7ee787RNST7ee787.T7ee787vendorT7ee787.T7ee787i2plib Tff7b72as T7ee787i2plib
Tff7b72import T7ee787RNST7ee787.T7ee787vendorT7ee787.T7ee787i2plibT7ee787.T7ee787utils

Tff7b72selfTff7b72.Td2a8ffclient_tunnels Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffserver_tunnels Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffi2plib_tunnels Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffloop Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffi2plib Tff7b72= Te6edf3i2plib
Tff7b72selfTff7b72.Td2a8ffutils Tff7b72= Te6edf3i2plibTff7b72.Td2a8ffutils
Tff7b72selfTff7b72.Td2a8ffsam_address Tff7b72= Te6edf3i2plibTff7b72.Td2a8ffget_sam_addressTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffready Tff7b72= Tff7b72False

Tff7b72selfTff7b72.Td2a8ffstoragepath Tff7b72= Te6edf3rns_storagepathTff7b72+Ta5d6ff"Ta5d6ff/i2pTa5d6ff"
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTb4b4b4)Tb4b4b4:
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstoragepathTb4b4b4)


Tff7b72def Td2a8ffstartTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3asyncioTff7b72.Td2a8ffset_event_loopTb4b4b4(Te6edf3asyncioTff7b72.Td2a8ffnew_event_loopTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffloop Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffget_event_loopTb4b4b4(Tb4b4b4)

Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.10Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffloop Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not get event loop for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, waiting for event loop to appearTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Tff7b72while Tff7b72selfTff7b72.Td2a8ffloop Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloop Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffget_event_loopTb4b4b4(Tb4b4b4)
Te6edf3sleepTb4b4b4(T79c0ff0.25Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffready Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffloopTff7b72.Td2a8ffrun_foreverTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffready Tff7b72= Tff7b72False
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffException on event loop for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72finallyTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffloopTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffstopTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3i2ptunnel Tff7b72in Tff7b72selfTff7b72.Td2a8ffi2plib_tunnelsTb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3i2ptunnelTb4b4b4, Ta5d6ff"Ta5d6ffstopTa5d6ff"Tb4b4b4) Tff7b72and Tffa657callableTb4b4b4(Te6edf3i2ptunnelTff7b72.Td2a8ffstopTb4b4b4)Tb4b4b4:
Te6edf3i2ptunnelTff7b72.Td2a8ffstopTb4b4b4(Tb4b4b4)

Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3asyncioTff7b72.Td2a8ffTaskTb4b4b4, Ta5d6ff"Ta5d6ffall_tasksTa5d6ff"Tb4b4b4) Tff7b72and Tffa657callableTb4b4b4(Te6edf3asyncioTff7b72.Td2a8ffTaskTff7b72.Td2a8ffall_tasksTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3task Tff7b72in Te6edf3asyncioTff7b72.Td2a8ffTaskTff7b72.Td2a8ffall_tasksTb4b4b4(Te6edf3loopTff7b72=Tff7b72selfTff7b72.Td2a8ffloopTb4b4b4)Tb4b4b4:
Te6edf3taskTff7b72.Td2a8ffcancelTb4b4b4(Tb4b4b4)

Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.2Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffloopTff7b72.Td2a8ffstopTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffget_free_portTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffutilsTff7b72.Td2a8ffget_free_portTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffstop_tunnelTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3i2ptunnelTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3i2ptunnelTb4b4b4, Ta5d6ff"Ta5d6ffstopTa5d6ff"Tb4b4b4) Tff7b72and Tffa657callableTb4b4b4(Te6edf3i2ptunnelTff7b72.Td2a8ffstopTb4b4b4)Tb4b4b4:
Te6edf3i2ptunnelTff7b72.Td2a8ffstopTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffclient_tunnelTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3ownerTb4b4b4, Te6edf3i2p_destinationTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffclient_tunnelsTb4b4b4[Te6edf3i2p_destinationTb4b4b4] Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffi2plib_tunnelsTb4b4b4[Te6edf3i2p_destinationTb4b4b4] Tff7b72= Tff7b72None

Tff7b72while Tff7b72TrueTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffclient_tunnelsTb4b4b4[Te6edf3i2p_destinationTb4b4b4]Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72async Tff7b72def Td2a8fftunnel_upTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffBringing up I2P tunnel to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3ownerTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, this may take a while...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_INFOTb4b4b4)
Te6edf3tunnel Tff7b72= Tff7b72selfTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffClientTunnelTb4b4b4(Te6edf3i2p_destinationTb4b4b4, Te6edf3ownerTff7b72.Td2a8fflocal_addrTb4b4b4, Te6edf3sam_addressTff7b72=Tff7b72selfTff7b72.Td2a8ffsam_addressTb4b4b4, Te6edf3loopTff7b72=Tff7b72selfTff7b72.Td2a8ffloopTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffi2plib_tunnelsTb4b4b4[Te6edf3i2p_destinationTb4b4b4] Tff7b72= Te6edf3tunnel
Tff7b72await Te6edf3tunnelTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffloopTff7b72.Td2a8ffext_owner Tff7b72= Tff7b72self
Te6edf3result Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffrun_coroutine_threadsafeTb4b4b4(Te6edf3tunnel_upTb4b4b4(Tb4b4b4)Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffloopTb4b4b4)Tff7b72.Td2a8ffresultTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3i2p_destination Tff7b72in Tff7b72selfTff7b72.Td2a8ffi2plib_tunnelsTb4b4b4:
Tff7b72raise Tf85149IOErrorTb4b4b4(Ta5d6ff"Ta5d6ffNo tunnel control instance was createdTa5d6ff"Tb4b4b4)

Tff7b72elseTb4b4b4:
Te6edf3tn Tff7b72= Tff7b72selfTff7b72.Td2a8ffi2plib_tunnelsTb4b4b4[Te6edf3i2p_destinationTb4b4b4]
Tff7b72if Te6edf3tn Tff7b72!= Tff7b72None Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3tnTb4b4b4, Ta5d6ff"Ta5d6ffstatusTa5d6ff"Tb4b4b4)Tb4b4b4:

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffWaiting for status from I2P control processTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)
Tff7b72while Tff7b72not Te6edf3tnTff7b72.Td2a8ffstatusTb4b4b4[Ta5d6ff"Ta5d6ffsetup_ranTa5d6ff"Tb4b4b4]Tb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.1Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffGot status from I2P control processTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4)

Tff7b72if Te6edf3tnTff7b72.Td2a8ffstatusTb4b4b4[Ta5d6ff"Ta5d6ffsetup_failedTa5d6ff"Tb4b4b4]Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstop_tunnelTb4b4b4(Te6edf3tnTb4b4b4)
Tff7b72raise Te6edf3tnTff7b72.Td2a8ffstatusTb4b4b4[Ta5d6ff"Ta5d6ffexceptionTa5d6ff"Tb4b4b4]

Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3ownerTff7b72.Td2a8ffsocket Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3ownerTff7b72.Td2a8ffsocketTb4b4b4, Ta5d6ff"Ta5d6ffcloseTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72if Tffa657callableTb4b4b4(Te6edf3ownerTff7b72.Td2a8ffsocketTff7b72.Td2a8ffcloseTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3ownerTff7b72.Td2a8ffsocketTff7b72.Td2a8ffshutdownTb4b4b4(Te6edf3socketTff7b72.Td2a8ffSHUT_RDWRTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while shutting down socket for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3ownerTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)

Tff7b72tryTb4b4b4:
Te6edf3ownerTff7b72.Td2a8ffsocketTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while closing socket for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3ownerTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffclient_tunnelsTb4b4b4[Te6edf3i2p_destinationTb4b4b4] Tff7b72= Tff7b72True
Te6edf3ownerTff7b72.Td2a8ffawaiting_i2p_tunnel Tff7b72= Tff7b72False

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Te6edf3ownerTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff tunnel setup completeTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149IOErrorTb4b4b4(Ta5d6ff"Ta5d6ffGot no status response from SAM APITa5d6ff"Tb4b4b4)

Tff7b72except Tf85149ConnectionRefusedError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72raise Te6edf3e
Tff7b72except Tf85149ConnectionAbortedError Tff7b72as Te6edf3eTb4b4b4:
Tff7b72raise Te6edf3e

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffUnexpected error type from I2P SAM: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72raise Te6edf3e

Tff7b72elseTb4b4b4:
Te6edf3i2ptunnel Tff7b72= Tff7b72selfTff7b72.Td2a8ffi2plib_tunnelsTb4b4b4[Te6edf3i2p_destinationTb4b4b4]
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3i2ptunnelTb4b4b4, Ta5d6ff"Ta5d6ffstatusTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3i2p_exception Tff7b72= Te6edf3i2ptunnelTff7b72.Td2a8ffstatusTb4b4b4[Ta5d6ff"Ta5d6ffexceptionTa5d6ff"Tb4b4b4]

Tff7b72if Te6edf3i2ptunnelTff7b72.Td2a8ffstatusTb4b4b4[Ta5d6ff"Ta5d6ffsetup_ranTa5d6ff"Tb4b4b4] Tff7b72== Tff7b72FalseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff I2P tunnel setup did not completeTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffstop_tunnelTb4b4b4(Te6edf3i2ptunnelTb4b4b4)
Tff7b72return Tff7b72False

Tff7b72elif Te6edf3i2p_exception Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAn error ocurred while setting up I2P tunnel to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffCantReachPeerTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon canTa5d6ff'Ta5d6fft reach peer Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffDuplicatedDestTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon reported that the destination is already in useTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffDuplicatedIdTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon reported that the ID is arleady in useTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffInvalidIdTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon reported that the stream session ID doesnTa5d6ff'Ta5d6fft existTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffInvalidKeyTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon reported that the key for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff is invalidTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffKeyNotFoundTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon could not find the key for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffPeerNotFoundTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon mould not find the peer Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffI2PErrorTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon experienced an unspecified errorTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffTimeoutTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffI2P daemon timed out while setting up client tunnel to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffResetting I2P tunnel and retrying laterTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffstop_tunnelTb4b4b4(Te6edf3i2ptunnelTb4b4b4)
Tff7b72return Tff7b72False

Tff7b72elif Te6edf3i2ptunnelTff7b72.Td2a8ffstatusTb4b4b4[Ta5d6ff"Ta5d6ffsetup_failedTa5d6ff"Tb4b4b4] Tff7b72== Tff7b72TrueTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff Unspecified I2P tunnel setup error, resetting I2P tunnelTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffstop_tunnelTb4b4b4(Te6edf3i2ptunnelTb4b4b4)
Tff7b72return Tff7b72False

Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff Got no status from SAM API, resetting I2P tunnelTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffstop_tunnelTb4b4b4(Te6edf3i2ptunnelTb4b4b4)
Tff7b72return Tff7b72False

T8b949e# Wait for status from I2P control process
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff5Tb4b4b4)


Tff7b72def Td2a8ffserver_tunnelTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3ownerTb4b4b4)Tb4b4b4:
Tff7b72while Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffidentity Tff7b72== Tff7b72NoneTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff1Tb4b4b4)

T8b949e# Old format
Te6edf3i2p_dest_hash_of Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3ownerTff7b72.Td2a8ffnameTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3i2p_keyfile_of Tff7b72= Tff7b72selfTff7b72.Td2a8ffstoragepathTff7b72+Ta5d6ff"Ta5d6ff/Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3i2p_dest_hash_ofTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff.i2pTa5d6ff"

T8b949e# New format
Te6edf3i2p_dest_hash_nf Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3ownerTff7b72.Td2a8ffnameTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)Tff7b72+Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4)
Te6edf3i2p_keyfile_nf Tff7b72= Tff7b72selfTff7b72.Td2a8ffstoragepathTff7b72+Ta5d6ff"Ta5d6ff/Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffhexrepTb4b4b4(Te6edf3i2p_dest_hash_nfTb4b4b4, Te6edf3delimitTff7b72=Tff7b72FalseTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff.i2pTa5d6ff"

T8b949e# Use old format if a key is already present
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3i2p_keyfile_ofTb4b4b4)Tb4b4b4:
Te6edf3i2p_keyfile Tff7b72= Te6edf3i2p_keyfile_of
Tff7b72elseTb4b4b4:
Te6edf3i2p_keyfile Tff7b72= Te6edf3i2p_keyfile_nf

Te6edf3i2p_dest Tff7b72= Tff7b72None
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3i2p_keyfileTb4b4b4)Tb4b4b4:
Te6edf3coro Tff7b72= Tff7b72selfTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffnew_destinationTb4b4b4(Te6edf3sam_addressTff7b72=Tff7b72selfTff7b72.Td2a8ffsam_addressTb4b4b4, Te6edf3loopTff7b72=Tff7b72selfTff7b72.Td2a8ffloopTb4b4b4)
Te6edf3i2p_dest Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffrun_coroutine_threadsafeTb4b4b4(Te6edf3coroTb4b4b4, Tff7b72selfTff7b72.Td2a8ffloopTb4b4b4)Tff7b72.Td2a8ffresultTb4b4b4(Tb4b4b4)
Te6edf3key_file Tff7b72= Tffa657openTb4b4b4(Te6edf3i2p_keyfileTb4b4b4, Ta5d6ff"Ta5d6ffwTa5d6ff"Tb4b4b4)
Te6edf3key_fileTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3i2p_destTff7b72.Td2a8ffprivate_keyTff7b72.Td2a8ffbase64Tb4b4b4)
Te6edf3key_fileTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3key_file Tff7b72= Tffa657openTb4b4b4(Te6edf3i2p_keyfileTb4b4b4, Ta5d6ff"Ta5d6ffrTa5d6ff"Tb4b4b4)
Te6edf3prvd Tff7b72= Te6edf3key_fileTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Te6edf3key_fileTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Te6edf3i2p_dest Tff7b72= Tff7b72selfTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffDestinationTb4b4b4(Te6edf3dataTff7b72=Te6edf3prvdTb4b4b4, Te6edf3has_private_keyTff7b72=Tff7b72TrueTb4b4b4)

Te6edf3i2p_b32 Tff7b72= Te6edf3i2p_destTff7b72.Td2a8ffbase32
Te6edf3ownerTff7b72.Td2a8ffb32 Tff7b72= Te6edf3i2p_b32

Tff7b72selfTff7b72.Td2a8ffserver_tunnelsTb4b4b4[Te6edf3i2p_b32Tb4b4b4] Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffi2plib_tunnelsTb4b4b4[Te6edf3i2p_b32Tb4b4b4] Tff7b72= Tff7b72None

Tff7b72while Tff7b72TrueTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffserver_tunnelsTb4b4b4[Te6edf3i2p_b32Tb4b4b4] Tff7b72== Tff7b72FalseTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72async Tff7b72def Td2a8fftunnel_upTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Te6edf3ownerTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff Bringing up I2P endpoint, this may take a while...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_INFOTb4b4b4)
Te6edf3tunnel Tff7b72= Tff7b72selfTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffServerTunnelTb4b4b4(Tb4b4b4(Te6edf3ownerTff7b72.Td2a8ffbind_ipTb4b4b4, Te6edf3ownerTff7b72.Td2a8ffbind_portTb4b4b4)Tb4b4b4, Te6edf3loopTff7b72=Tff7b72selfTff7b72.Td2a8ffloopTb4b4b4, Te6edf3destinationTff7b72=Te6edf3i2p_destTb4b4b4, Te6edf3sam_addressTff7b72=Tff7b72selfTff7b72.Td2a8ffsam_addressTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffi2plib_tunnelsTb4b4b4[Te6edf3i2p_b32Tb4b4b4] Tff7b72= Te6edf3tunnel
Tff7b72await Te6edf3tunnelTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4)
Te6edf3ownerTff7b72.Td2a8ffonline Tff7b72= Tff7b72True
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Te6edf3ownerTb4b4b4)Tff7b72+ Ta5d6ff"Ta5d6ff endpoint setup complete. Now reachable at: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destTff7b72.Td2a8ffbase32Tb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff.b32.i2pTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Te6edf3asyncioTff7b72.Td2a8ffrun_coroutine_threadsafeTb4b4b4(Te6edf3tunnel_upTb4b4b4(Tb4b4b4)Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffloopTb4b4b4)Tff7b72.Td2a8ffresultTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffserver_tunnelsTb4b4b4[Te6edf3i2p_b32Tb4b4b4] Tff7b72= Tff7b72True

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72raise Te6edf3e

Tff7b72elseTb4b4b4:
Te6edf3i2ptunnel Tff7b72= Tff7b72selfTff7b72.Td2a8ffi2plib_tunnelsTb4b4b4[Te6edf3i2p_b32Tb4b4b4]
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3i2ptunnelTb4b4b4, Ta5d6ff"Ta5d6ffstatusTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3i2p_exception Tff7b72= Te6edf3i2ptunnelTff7b72.Td2a8ffstatusTb4b4b4[Ta5d6ff"Ta5d6ffexceptionTa5d6ff"Tb4b4b4]

Tff7b72if Te6edf3i2ptunnelTff7b72.Td2a8ffstatusTb4b4b4[Ta5d6ff"Ta5d6ffsetup_ranTa5d6ff"Tb4b4b4] Tff7b72== Tff7b72FalseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff I2P tunnel setup did not completeTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffstop_tunnelTb4b4b4(Te6edf3i2ptunnelTb4b4b4)
Tff7b72return Tff7b72False

Tff7b72elif Te6edf3i2p_exception Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAn error ocurred while setting up I2P tunnelTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffCantReachPeerTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon canTa5d6ff'Ta5d6fft reach peer Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffDuplicatedDestTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon reported that the destination is already in useTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffDuplicatedIdTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon reported that the ID is arleady in useTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffInvalidIdTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon reported that the stream session ID doesnTa5d6ff'Ta5d6fft existTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffInvalidKeyTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon reported that the key for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff is invalidTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffKeyNotFoundTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon could not find the key for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffPeerNotFoundTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon mould not find the peer Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffI2PErrorTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe I2P daemon experienced an unspecified errorTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elif Tffa657isinstanceTb4b4b4(Te6edf3i2p_exceptionTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffvendorTff7b72.Td2a8ffi2plibTff7b72.Td2a8ffexceptionsTff7b72.Td2a8ffTimeoutTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffI2P daemon timed out while setting up client tunnel to Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3i2p_destinationTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffResetting I2P tunnel and retrying laterTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffstop_tunnelTb4b4b4(Te6edf3i2ptunnelTb4b4b4)
Tff7b72return Tff7b72False

Tff7b72elif Te6edf3i2ptunnelTff7b72.Td2a8ffstatusTb4b4b4[Ta5d6ff"Ta5d6ffsetup_failedTa5d6ff"Tb4b4b4] Tff7b72== Tff7b72TrueTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff Unspecified I2P tunnel setup error, resetting I2P tunnelTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffstop_tunnelTb4b4b4(Te6edf3i2ptunnelTb4b4b4)
Tff7b72return Tff7b72False

Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff Got no status from SAM API, resetting I2P tunnelTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffstop_tunnelTb4b4b4(Te6edf3i2ptunnelTb4b4b4)
Tff7b72return Tff7b72False

Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff5Tb4b4b4)

Tff7b72def Td2a8ffget_loopTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3asyncioTff7b72.Td2a8ffget_event_loopTb4b4b4(Tb4b4b4)


Tff7b72class T56d364ThreadingI2PServerTb4b4b4(Te6edf3socketserverTff7b72.Td2a8ffThreadingMixInTb4b4b4, Te6edf3socketserverTff7b72.Td2a8ffTCPServerTb4b4b4)Tb4b4b4:
Tff7b72pass

Tff7b72class T56d364I2PInterfacePeerTb4b4b4(Te6edf3InterfaceTb4b4b4)Tb4b4b4:
Te6edf3RECONNECT_WAIT Tff7b72= T79c0ff15
Te6edf3RECONNECT_MAX_TRIES Tff7b72= Tff7b72None

T8b949e# TCP socket options
Te6edf3I2P_USER_TIMEOUT Tff7b72= T79c0ff45
Te6edf3I2P_PROBE_AFTER Tff7b72= T79c0ff10
Te6edf3I2P_PROBE_INTERVAL Tff7b72= T79c0ff9
Te6edf3I2P_PROBES Tff7b72= T79c0ff5
Te6edf3I2P_READ_TIMEOUT Tff7b72= Tb4b4b4(Te6edf3I2P_PROBE_INTERVAL Tff7b72* Te6edf3I2P_PROBES Tff7b72+ Te6edf3I2P_PROBE_AFTERTb4b4b4)Tff7b72*T79c0ff2

Te6edf3TUNNEL_STATE_INIT Tff7b72= T79c0ff0x00
Te6edf3TUNNEL_STATE_ACTIVE Tff7b72= T79c0ff0x01
Te6edf3TUNNEL_STATE_STALE Tff7b72= T79c0ff0x02

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3parent_interfaceTb4b4b4, Te6edf3ownerTb4b4b4, Te6edf3nameTb4b4b4, Te6edf3target_i2p_destTff7b72=Tff7b72NoneTb4b4b4, Te6edf3connected_socketTff7b72=Tff7b72NoneTb4b4b4, Te6edf3max_reconnect_triesTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffHW_MTU Tff7b72= T79c0ff1064
Tff7b72selfTff7b72.Td2a8ffIN Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffOUT Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffsocket Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffparent_interface Tff7b72= Te6edf3parent_interface
Tff7b72selfTff7b72.Td2a8ffparent_count Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffname Tff7b72= Te6edf3name
Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffreconnecting Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffnever_connected Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffowner Tff7b72= Te6edf3owner
Tff7b72selfTff7b72.Td2a8ffwriting Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffdetached Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffkiss_framing Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffi2p_tunneled Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffi2p_dest Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffi2p_tunnel_ready Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffmode Tff7b72= Te6edf3RNSTff7b72.Td2a8ffInterfacesTff7b72.Td2a8ffInterfaceTff7b72.Td2a8ffInterfaceTff7b72.Td2a8ffMODE_FULL
Tff7b72selfTff7b72.Td2a8ffbitrate Tff7b72= Te6edf3I2PInterfaceTff7b72.Td2a8ffBITRATE_GUESS
Tff7b72selfTff7b72.Td2a8fflast_read Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8fflast_write Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffwd_reset Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffi2p_tunnel_state Tff7b72= Te6edf3I2PInterfacePeerTff7b72.Td2a8ffTUNNEL_STATE_INIT

Tff7b72selfTff7b72.Td2a8ffifac_size Tff7b72= Tff7b72selfTff7b72.Td2a8ffparent_interfaceTff7b72.Td2a8ffifac_size
Tff7b72selfTff7b72.Td2a8ffifac_netname Tff7b72= Tff7b72selfTff7b72.Td2a8ffparent_interfaceTff7b72.Td2a8ffifac_netname
Tff7b72selfTff7b72.Td2a8ffifac_netkey Tff7b72= Tff7b72selfTff7b72.Td2a8ffparent_interfaceTff7b72.Td2a8ffifac_netkey
Tff7b72if Tff7b72selfTff7b72.Td2a8ffifac_netname Tff7b72!= Tff7b72None Tff7b72or Tff7b72selfTff7b72.Td2a8ffifac_netkey Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ifac_origin Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"
Tff7b72if Tff7b72selfTff7b72.Td2a8ffifac_netname Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ifac_origin Tff7b72+Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Tff7b72selfTff7b72.Td2a8ffifac_netnameTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffifac_netkey Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ifac_origin Tff7b72+Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Tff7b72selfTff7b72.Td2a8ffifac_netkeyTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3ifac_origin_hash Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3ifac_originTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffifac_key Tff7b72= Te6edf3RNSTff7b72.Td2a8ffCryptographyTff7b72.Td2a8ffhkdfTb4b4b4(
Te6edf3lengthTff7b72=T79c0ff64Tb4b4b4,
Te6edf3derive_fromTff7b72=Te6edf3ifac_origin_hashTb4b4b4,
Te6edf3saltTff7b72=Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffIFAC_SALTTb4b4b4,
Te6edf3contextTff7b72=Tff7b72None
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffifac_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffrom_bytesTb4b4b4(Tff7b72selfTff7b72.Td2a8ffifac_keyTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffifac_signature Tff7b72= Tff7b72selfTff7b72.Td2a8ffifac_identityTff7b72.Td2a8ffsignTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Tff7b72selfTff7b72.Td2a8ffifac_keyTb4b4b4)Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffannounce_rate_target Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffannounce_rate_grace Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffannounce_rate_penalty Tff7b72= Tff7b72None

Tff7b72if Te6edf3max_reconnect_tries Tff7b72== Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmax_reconnect_tries Tff7b72= Te6edf3I2PInterfacePeerTff7b72.Td2a8ffRECONNECT_MAX_TRIES
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffmax_reconnect_tries Tff7b72= Te6edf3max_reconnect_tries

Tff7b72if Te6edf3connected_socket Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffreceives Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8fftarget_ip Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8fftarget_port Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffsocket Tff7b72= Te6edf3connected_socket

Tff7b72if Te6edf3platformTff7b72.Td2a8ffsystemTb4b4b4(Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffLinuxTa5d6ff"Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffset_timeouts_linuxTb4b4b4(Tb4b4b4)
Tff7b72elif Te6edf3platformTff7b72.Td2a8ffsystemTb4b4b4(Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffDarwinTa5d6ff"Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffset_timeouts_osxTb4b4b4(Tb4b4b4)

Tff7b72elif Te6edf3target_i2p_dest Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffreceives Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72= Tff7b72True

Tff7b72selfTff7b72.Td2a8ffbind_ip Tff7b72= Ta5d6ff"Ta5d6ff127.0.0.1Ta5d6ff"

Tff7b72selfTff7b72.Td2a8ffawaiting_i2p_tunnel Tff7b72= Tff7b72True

Tff7b72def Td2a8fftunnel_jobTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72selfTff7b72.Td2a8ffawaiting_i2p_tunnelTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffbind_port Tff7b72= Tff7b72selfTff7b72.Td2a8ffparent_interfaceTff7b72.Td2a8ffi2pTff7b72.Td2a8ffget_free_portTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflocal_addr Tff7b72= Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffbind_ipTb4b4b4, Tff7b72selfTff7b72.Td2a8ffbind_portTb4b4b4)
Tff7b72selfTff7b72.Td2a8fftarget_ip Tff7b72= Tff7b72selfTff7b72.Td2a8ffbind_ip
Tff7b72selfTff7b72.Td2a8fftarget_port Tff7b72= Tff7b72selfTff7b72.Td2a8ffbind_port

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffparent_interfaceTff7b72.Td2a8ffi2pTff7b72.Td2a8ffclient_tunnelTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3target_i2p_destTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff I2P control process experienced an error, requesting new tunnel...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffawaiting_i2p_tunnel Tff7b72= Tff7b72True

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while while configuring Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCheck that I2P is installed and running, and that SAM is enabled. Retrying tunnel setup later.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff8Tb4b4b4)

Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3tunnel_jobTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffwait_jobTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72selfTff7b72.Td2a8ffawaiting_i2p_tunnelTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.25Tb4b4b4)
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff2Tb4b4b4)
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffkiss_framingTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwants_tunnel Tff7b72= Tff7b72True

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffconnectTb4b4b4(Te6edf3initialTff7b72=Tff7b72TrueTb4b4b4)Tb4b4b4:
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffreconnectTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffread_loopTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3wait_jobTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffset_timeouts_linuxTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffsetsockoptTb4b4b4(Te6edf3socketTff7b72.Td2a8ffIPPROTO_TCPTb4b4b4, Te6edf3socketTff7b72.Td2a8ffTCP_USER_TIMEOUTTb4b4b4, Tffa657intTb4b4b4(Te6edf3I2PInterfacePeerTff7b72.Td2a8ffI2P_USER_TIMEOUT Tff7b72* T79c0ff1000Tb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffsetsockoptTb4b4b4(Te6edf3socketTff7b72.Td2a8ffSOL_SOCKETTb4b4b4, Te6edf3socketTff7b72.Td2a8ffSO_KEEPALIVETb4b4b4, T79c0ff1Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffsetsockoptTb4b4b4(Te6edf3socketTff7b72.Td2a8ffIPPROTO_TCPTb4b4b4, Te6edf3socketTff7b72.Td2a8ffTCP_KEEPIDLETb4b4b4, Tffa657intTb4b4b4(Te6edf3I2PInterfacePeerTff7b72.Td2a8ffI2P_PROBE_AFTERTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffsetsockoptTb4b4b4(Te6edf3socketTff7b72.Td2a8ffIPPROTO_TCPTb4b4b4, Te6edf3socketTff7b72.Td2a8ffTCP_KEEPINTVLTb4b4b4, Tffa657intTb4b4b4(Te6edf3I2PInterfacePeerTff7b72.Td2a8ffI2P_PROBE_INTERVALTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffsetsockoptTb4b4b4(Te6edf3socketTff7b72.Td2a8ffIPPROTO_TCPTb4b4b4, Te6edf3socketTff7b72.Td2a8ffTCP_KEEPCNTTb4b4b4, Tffa657intTb4b4b4(Te6edf3I2PInterfacePeerTff7b72.Td2a8ffI2P_PROBESTb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffset_timeouts_osxTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3socketTb4b4b4, Ta5d6ff"Ta5d6ffTCP_KEEPALIVETa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3TCP_KEEPIDLE Tff7b72= Te6edf3socketTff7b72.Td2a8ffTCP_KEEPALIVE
Tff7b72elseTb4b4b4:
Te6edf3TCP_KEEPIDLE Tff7b72= T79c0ff0x10

Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffsetsockoptTb4b4b4(Te6edf3socketTff7b72.Td2a8ffSOL_SOCKETTb4b4b4, Te6edf3socketTff7b72.Td2a8ffSO_KEEPALIVETb4b4b4, T79c0ff1Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffsetsockoptTb4b4b4(Te6edf3socketTff7b72.Td2a8ffIPPROTO_TCPTb4b4b4, Te6edf3TCP_KEEPIDLETb4b4b4, Tffa657intTb4b4b4(Te6edf3I2PInterfacePeerTff7b72.Td2a8ffI2P_PROBE_AFTERTb4b4b4)Tb4b4b4)
Tff7b72def Td2a8ffshutdown_socketTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3target_socketTb4b4b4)Tb4b4b4:
Tff7b72if Tffa657callableTb4b4b4(Te6edf3target_socketTff7b72.Td2a8ffcloseTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3socket Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3target_socketTff7b72.Td2a8ffshutdownTb4b4b4(Te6edf3socketTff7b72.Td2a8ffSHUT_RDWRTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while shutting down socket for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3socket Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3target_socketTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while closing socket for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)
Tff7b72def Td2a8ffdetachTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDetaching Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffsocket Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsocketTb4b4b4, Ta5d6ff"Ta5d6ffcloseTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72if Tffa657callableTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffcloseTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffdetached Tff7b72= Tff7b72True
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffshutdownTb4b4b4(Te6edf3socketTff7b72.Td2a8ffSHUT_RDWRTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while shutting down socket for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while closing socket for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffsocket Tff7b72= Tff7b72None

Tff7b72def Td2a8ffconnectTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3initialTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsocket Tff7b72= Te6edf3socketTff7b72.Td2a8ffsocketTb4b4b4(Te6edf3socketTff7b72.Td2a8ffAF_INETTb4b4b4, Te6edf3socketTff7b72.Td2a8ffSOCK_STREAMTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffconnectTb4b4b4(Tb4b4b4(Tff7b72selfTff7b72.Td2a8fftarget_ipTb4b4b4, Tff7b72selfTff7b72.Td2a8fftarget_portTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72True
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72if Te6edf3initialTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffawaiting_i2p_tunnelTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffInitial connection for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff could not be established: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLeaving unconnected and retrying connection in Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3I2PInterfacePeerTff7b72.Td2a8ffRECONNECT_WAITTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff seconds.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72return Tff7b72False
Tff7b72elseTb4b4b4:
Tff7b72raise Te6edf3e

Tff7b72if Te6edf3platformTff7b72.Td2a8ffsystemTb4b4b4(Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffLinuxTa5d6ff"Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffset_timeouts_linuxTb4b4b4(Tb4b4b4)
Tff7b72elif Te6edf3platformTff7b72.Td2a8ffsystemTb4b4b4(Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffDarwinTa5d6ff"Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffset_timeouts_osxTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffwriting Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffnever_connected Tff7b72= Tff7b72False

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffkiss_framing Tff7b72and Tff7b72selfTff7b72.Td2a8ffwants_tunnelTb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffsynthesize_tunnelTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72return Tff7b72True

Tff7b72def Td2a8ffreconnectTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiatorTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffreconnectingTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffreconnecting Tff7b72= Tff7b72True
Te6edf3attempts Tff7b72= T79c0ff0
Tff7b72while Tff7b72not Tff7b72selfTff7b72.Td2a8ffonlineTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(Te6edf3I2PInterfacePeerTff7b72.Td2a8ffRECONNECT_WAITTb4b4b4)
Te6edf3attempts Tff7b72+Tff7b72= T79c0ff1

Tff7b72if Tff7b72selfTff7b72.Td2a8ffmax_reconnect_tries Tff7b72!= Tff7b72None Tff7b72and Te6edf3attempts Tff7b72> Tff7b72selfTff7b72.Td2a8ffmax_reconnect_triesTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffMax reconnection attempts reached for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)
Tff7b72break

Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffconnectTb4b4b4(Tb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffawaiting_i2p_tunnelTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffConnection attempt for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff failed: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff still waiting for I2P tunnel to appearTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffnever_connectedTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff Re-established connection via I2P tunnelTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_INFOTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffreconnecting Tff7b72= Tff7b72False
Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffread_loopTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffkiss_framingTb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffsynthesize_tunnelTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to reconnect on a non-initiator I2P interface. This should not happen.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72raise Tf85149IOErrorTb4b4b4(Ta5d6ff"Ta5d6ffAttempt to reconnect on a non-initiator I2P interfaceTa5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffprocess_incomingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrxb Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTb4b4b4, Ta5d6ff"Ta5d6ffparent_interfaceTa5d6ff"Tb4b4b4) Tff7b72and Tff7b72selfTff7b72.Td2a8ffparent_interface Tff7b72!= Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ffparent_countTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffparent_interfaceTff7b72.Td2a8ffrxb Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffownerTff7b72.Td2a8ffinboundTb4b4b4(Te6edf3dataTb4b4b4, Tff7b72selfTb4b4b4)

Tff7b72def Td2a8ffprocess_outgoingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffonlineTb4b4b4:
Tff7b72while Tff7b72selfTff7b72.Td2a8ffwritingTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.001Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwriting Tff7b72= Tff7b72True

Tff7b72if Tff7b72selfTff7b72.Td2a8ffkiss_framingTb4b4b4:
Te6edf3data Tff7b72= Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3KISSTff7b72.Td2a8ffFENDTb4b4b4]Tb4b4b4)Tff7b72+Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3KISSTff7b72.Td2a8ffCMD_DATATb4b4b4]Tb4b4b4)Tff7b72+Te6edf3KISSTff7b72.Td2a8ffescapeTb4b4b4(Te6edf3dataTb4b4b4)Tff7b72+Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3KISSTff7b72.Td2a8ffFENDTb4b4b4]Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3data Tff7b72= Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3HDLCTff7b72.Td2a8ffFLAGTb4b4b4]Tb4b4b4)Tff7b72+Te6edf3HDLCTff7b72.Td2a8ffescapeTb4b4b4(Te6edf3dataTb4b4b4)Tff7b72+Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3HDLCTff7b72.Td2a8ffFLAGTb4b4b4]Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffsendallTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffwriting Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8fftxb Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_write Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTb4b4b4, Ta5d6ff"Ta5d6ffparent_interfaceTa5d6ff"Tb4b4b4) Tff7b72and Tff7b72selfTff7b72.Td2a8ffparent_interface Tff7b72!= Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ffparent_countTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffparent_interfaceTff7b72.Td2a8fftxb Tff7b72+Tff7b72= Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffException occurred while transmitting via Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, tearing down interfaceTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8ffread_watchdogTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72selfTff7b72.Td2a8ffwd_resetTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.25Tb4b4b4)

Te6edf3should_run Tff7b72= Tff7b72True
Tff7b72tryTb4b4b4:
Tff7b72while Te6edf3should_run Tff7b72and Tff7b72not Tff7b72selfTff7b72.Td2a8ffwd_resetTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff1Tb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72selfTff7b72.Td2a8fflast_read Tff7b72> Te6edf3I2PInterfacePeerTff7b72.Td2a8ffI2P_PROBE_AFTERTff7b72*T79c0ff2Tb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffi2p_tunnel_state Tff7b72!= Te6edf3I2PInterfacePeerTff7b72.Td2a8ffTUNNEL_STATE_STALETb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffI2P tunnel became unresponsiveTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffi2p_tunnel_state Tff7b72= Te6edf3I2PInterfacePeerTff7b72.Td2a8ffTUNNEL_STATE_STALE
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffi2p_tunnel_state Tff7b72= Te6edf3I2PInterfacePeerTff7b72.Td2a8ffTUNNEL_STATE_ACTIVE

Tff7b72if Tb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72selfTff7b72.Td2a8fflast_write Tff7b72> Te6edf3I2PInterfacePeerTff7b72.Td2a8ffI2P_PROBE_AFTERTff7b72*T79c0ff1Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffsocket Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffsendallTb4b4b4(Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3HDLCTff7b72.Td2a8ffFLAGTb4b4b4, Te6edf3HDLCTff7b72.Td2a8ffFLAGTb4b4b4]Tb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAn error ocurred while sending I2P keepalive. The contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffshutdown_socketTb4b4b4(Tff7b72selfTff7b72.Td2a8ffsocketTb4b4b4)
Te6edf3should_run Tff7b72= Tff7b72False
Tff7b72if Tb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72selfTff7b72.Td2a8fflast_read Tff7b72> Te6edf3I2PInterfacePeerTff7b72.Td2a8ffI2P_READ_TIMEOUTTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffI2P socket is unresponsive, restarting...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ffsocket Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffshutdownTb4b4b4(Te6edf3socketTff7b72.Td2a8ffSHUT_RDWRTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while shutting down socket for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)

Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while closing socket for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)

Te6edf3should_run Tff7b72= Tff7b72False

Tff7b72selfTff7b72.Td2a8ffwd_reset Tff7b72= Tff7b72False

Tff7b72finallyTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwd_reset Tff7b72= Tff7b72False

Tff7b72def Td2a8ffread_loopTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72selfTff7b72.Td2a8fflast_read Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_write Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Te6edf3wd_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffread_watchdogTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Te6edf3in_frame Tff7b72= Tff7b72False
Te6edf3escape Tff7b72= Tff7b72False
Te6edf3data_buffer Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"
Te6edf3command Tff7b72= Te6edf3KISSTff7b72.Td2a8ffCMD_UNKNOWN

Tff7b72while Tff7b72TrueTb4b4b4:
Te6edf3data_in Tff7b72= Tff7b72selfTff7b72.Td2a8ffsocketTff7b72.Td2a8ffrecvTb4b4b4(T79c0ff4096Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3data_inTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3pointer Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8fflast_read Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72while Te6edf3pointer Tff7b72< Tffa657lenTb4b4b4(Te6edf3data_inTb4b4b4)Tb4b4b4:
Te6edf3byte Tff7b72= Te6edf3data_inTb4b4b4[Te6edf3pointerTb4b4b4]
Te6edf3pointer Tff7b72+Tff7b72= T79c0ff1

Tff7b72if Tff7b72selfTff7b72.Td2a8ffkiss_framingTb4b4b4:
T8b949e# Read loop for KISS framing
Tff7b72if Tb4b4b4(Te6edf3in_frame Tff7b72and Te6edf3byte Tff7b72== Te6edf3KISSTff7b72.Td2a8ffFEND Tff7b72and Te6edf3command Tff7b72== Te6edf3KISSTff7b72.Td2a8ffCMD_DATATb4b4b4)Tb4b4b4:
Te6edf3in_frame Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffprocess_incomingTb4b4b4(Te6edf3data_bufferTb4b4b4)
Tff7b72elif Tb4b4b4(Te6edf3byte Tff7b72== Te6edf3KISSTff7b72.Td2a8ffFENDTb4b4b4)Tb4b4b4:
Te6edf3in_frame Tff7b72= Tff7b72True
Te6edf3command Tff7b72= Te6edf3KISSTff7b72.Td2a8ffCMD_UNKNOWN
Te6edf3data_buffer Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"
Tff7b72elif Tb4b4b4(Te6edf3in_frame Tff7b72and Tffa657lenTb4b4b4(Te6edf3data_bufferTb4b4b4) Tff7b72< Tff7b72selfTff7b72.Td2a8ffHW_MTUTb4b4b4)Tb4b4b4:
Tff7b72if Tb4b4b4(Tffa657lenTb4b4b4(Te6edf3data_bufferTb4b4b4) Tff7b72== T79c0ff0 Tff7b72and Te6edf3command Tff7b72== Te6edf3KISSTff7b72.Td2a8ffCMD_UNKNOWNTb4b4b4)Tb4b4b4:
T8b949e# We only support one HDLC port for now, so
T8b949e# strip off the port nibble
Te6edf3byte Tff7b72= Te6edf3byte Tff7b72& T79c0ff0x0F
Te6edf3command Tff7b72= Te6edf3byte
Tff7b72elif Tb4b4b4(Te6edf3command Tff7b72== Te6edf3KISSTff7b72.Td2a8ffCMD_DATATb4b4b4)Tb4b4b4:
Tff7b72if Tb4b4b4(Te6edf3byte Tff7b72== Te6edf3KISSTff7b72.Td2a8ffFESCTb4b4b4)Tb4b4b4:
Te6edf3escape Tff7b72= Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72if Tb4b4b4(Te6edf3escapeTb4b4b4)Tb4b4b4:
Tff7b72if Tb4b4b4(Te6edf3byte Tff7b72== Te6edf3KISSTff7b72.Td2a8ffTFENDTb4b4b4)Tb4b4b4:
Te6edf3byte Tff7b72= Te6edf3KISSTff7b72.Td2a8ffFEND
Tff7b72if Tb4b4b4(Te6edf3byte Tff7b72== Te6edf3KISSTff7b72.Td2a8ffTFESCTb4b4b4)Tb4b4b4:
Te6edf3byte Tff7b72= Te6edf3KISSTff7b72.Td2a8ffFESC
Te6edf3escape Tff7b72= Tff7b72False
Te6edf3data_buffer Tff7b72= Te6edf3data_bufferTff7b72+Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3byteTb4b4b4]Tb4b4b4)

Tff7b72elseTb4b4b4:
T8b949e# Read loop for HDLC framing
Tff7b72if Tb4b4b4(Te6edf3in_frame Tff7b72and Te6edf3byte Tff7b72== Te6edf3HDLCTff7b72.Td2a8ffFLAGTb4b4b4)Tb4b4b4:
Te6edf3in_frame Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffprocess_incomingTb4b4b4(Te6edf3data_bufferTb4b4b4)
Tff7b72elif Tb4b4b4(Te6edf3byte Tff7b72== Te6edf3HDLCTff7b72.Td2a8ffFLAGTb4b4b4)Tb4b4b4:
Te6edf3in_frame Tff7b72= Tff7b72True
Te6edf3data_buffer Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"
Tff7b72elif Tb4b4b4(Te6edf3in_frame Tff7b72and Tffa657lenTb4b4b4(Te6edf3data_bufferTb4b4b4) Tff7b72< Tff7b72selfTff7b72.Td2a8ffHW_MTUTb4b4b4)Tb4b4b4:
Tff7b72if Tb4b4b4(Te6edf3byte Tff7b72== Te6edf3HDLCTff7b72.Td2a8ffESCTb4b4b4)Tb4b4b4:
Te6edf3escape Tff7b72= Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72if Tb4b4b4(Te6edf3escapeTb4b4b4)Tb4b4b4:
Tff7b72if Tb4b4b4(Te6edf3byte Tff7b72== Te6edf3HDLCTff7b72.Td2a8ffFLAG Tff7b72^ Te6edf3HDLCTff7b72.Td2a8ffESC_MASKTb4b4b4)Tb4b4b4:
Te6edf3byte Tff7b72= Te6edf3HDLCTff7b72.Td2a8ffFLAG
Tff7b72if Tb4b4b4(Te6edf3byte Tff7b72== Te6edf3HDLCTff7b72.Td2a8ffESC Tff7b72^ Te6edf3HDLCTff7b72.Td2a8ffESC_MASKTb4b4b4)Tb4b4b4:
Te6edf3byte Tff7b72= Te6edf3HDLCTff7b72.Td2a8ffESC
Te6edf3escape Tff7b72= Tff7b72False
Te6edf3data_buffer Tff7b72= Te6edf3data_bufferTff7b72+Tffa657bytesTb4b4b4(Tb4b4b4[Te6edf3byteTb4b4b4]Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72False

Tff7b72selfTff7b72.Td2a8ffwd_reset Tff7b72= Tff7b72True
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff2Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffwd_reset Tff7b72= Tff7b72False

Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72and Tff7b72not Tff7b72selfTff7b72.Td2a8ffdetachedTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffSocket for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff was closed, attempting to reconnect...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffreconnectTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffSocket for remote client Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff was closed.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72selfTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)

Tff7b72break

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72False
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAn interface error occurred for Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff, the contained exception was: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiatorTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAttempting to reconnect...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffreconnectTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffteardownTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffinitiator Tff7b72and Tff7b72not Tff7b72selfTff7b72.Td2a8ffdetachedTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe interface Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff experienced an unrecoverable error and is being torn down. Restart Reticulum to attempt to open this interface again.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72if Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffpanic_on_interface_errorTb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffpanicTb4b4b4(Tb4b4b4)

Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe interface Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff is being torn down.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffOUT Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffIN Tff7b72= Tff7b72False

Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTb4b4b4, Ta5d6ff"Ta5d6ffparent_interfaceTa5d6ff"Tb4b4b4) Tff7b72and Tff7b72selfTff7b72.Td2a8ffparent_interface Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72while Tff7b72self Tff7b72in Tff7b72selfTff7b72.Td2a8ffparent_interfaceTff7b72.Td2a8ffspawned_interfacesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffparent_interfaceTff7b72.Td2a8ffspawned_interfacesTff7b72.Td2a8ffremoveTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffinitiatorTb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffremove_interfaceTb4b4b4(Tff7b72selfTb4b4b4)


Tff7b72def Tff7b72__str__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffI2PInterfacePeer[Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTff7b72.Td2a8ffnameTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff]Ta5d6ff"


Tff7b72class T56d364I2PInterfaceTb4b4b4(Te6edf3InterfaceTb4b4b4)Tb4b4b4:
Te6edf3BITRATE_GUESS Tff7b72= T79c0ff256Tff7b72*T79c0ff1000
Te6edf3DEFAULT_IFAC_SIZE Tff7b72= T79c0ff16

Tf0883e@property
Tff7b72def Td2a8ffclientsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTb4b4b4)

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3ownerTb4b4b4, Te6edf3configurationTb4b4b4)Tb4b4b4:
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Tb4b4b4)

Te6edf3c Tff7b72= Te6edf3InterfaceTff7b72.Td2a8ffget_config_objTb4b4b4(Te6edf3configurationTb4b4b4)
Te6edf3name Tff7b72= Te6edf3cTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4]
Te6edf3rns_storagepath Tff7b72= Te6edf3cTb4b4b4[Ta5d6ff"Ta5d6ffstoragepathTa5d6ff"Tb4b4b4]
Te6edf3peers Tff7b72= Te6edf3cTff7b72.Td2a8ffas_listTb4b4b4(Ta5d6ff"Ta5d6ffpeersTa5d6ff"Tb4b4b4) Tff7b72if Ta5d6ff"Ta5d6ffpeersTa5d6ff" Tff7b72in Te6edf3c Tff7b72else Tff7b72None
Te6edf3connectable Tff7b72= Te6edf3cTff7b72.Td2a8ffas_boolTb4b4b4(Ta5d6ff"Ta5d6ffconnectableTa5d6ff"Tb4b4b4) Tff7b72if Ta5d6ff"Ta5d6ffconnectableTa5d6ff" Tff7b72in Te6edf3c Tff7b72else Tff7b72False
Te6edf3ifac_size Tff7b72= Te6edf3cTb4b4b4[Ta5d6ff"Ta5d6ffifac_sizeTa5d6ff"Tb4b4b4] Tff7b72if Ta5d6ff"Ta5d6ffifac_sizeTa5d6ff" Tff7b72in Te6edf3c Tff7b72else Tff7b72None
Te6edf3ifac_netname Tff7b72= Te6edf3cTb4b4b4[Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4] Tff7b72if Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff" Tff7b72in Te6edf3c Tff7b72else Tff7b72None
Te6edf3ifac_netkey Tff7b72= Te6edf3cTb4b4b4[Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4] Tff7b72if Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff" Tff7b72in Te6edf3c Tff7b72else Tff7b72None
Tff7b72selfTff7b72.Td2a8ffHW_MTU Tff7b72= T79c0ff1064

Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffspawned_interfaces Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ffowner Tff7b72= Te6edf3owner
Tff7b72selfTff7b72.Td2a8ffconnectable Tff7b72= Te6edf3connectable
Tff7b72selfTff7b72.Td2a8ffi2p_tunneled Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffmode Tff7b72= Te6edf3RNSTff7b72.Td2a8ffInterfacesTff7b72.Td2a8ffInterfaceTff7b72.Td2a8ffInterfaceTff7b72.Td2a8ffMODE_FULL

Tff7b72selfTff7b72.Td2a8ffb32 Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffi2p Tff7b72= Te6edf3I2PControllerTb4b4b4(Te6edf3rns_storagepathTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffIN Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffOUT Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffname Tff7b72= Te6edf3name


Tff7b72selfTff7b72.Td2a8ffreceives Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffbind_ip Tff7b72= Ta5d6ff"Ta5d6ff127.0.0.1Ta5d6ff"
Tff7b72selfTff7b72.Td2a8ffbind_port Tff7b72= Tff7b72selfTff7b72.Td2a8ffi2pTff7b72.Td2a8ffget_free_portTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffaddress Tff7b72= Tb4b4b4(Tff7b72selfTff7b72.Td2a8ffbind_ipTb4b4b4, Tff7b72selfTff7b72.Td2a8ffbind_portTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffbitrate Tff7b72= Te6edf3I2PInterfaceTff7b72.Td2a8ffBITRATE_GUESS
Tff7b72selfTff7b72.Td2a8ffifac_size Tff7b72= Te6edf3ifac_size
Tff7b72selfTff7b72.Td2a8ffifac_netname Tff7b72= Te6edf3ifac_netname
Tff7b72selfTff7b72.Td2a8ffifac_netkey Tff7b72= Te6edf3ifac_netkey
Tff7b72selfTff7b72.Td2a8ffsupports_discovery Tff7b72= Tff7b72True

Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72False

Te6edf3i2p_thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffi2pTff7b72.Td2a8ffstartTb4b4b4)
Te6edf3i2p_threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3i2p_threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Te6edf3i2p_notready_warning Tff7b72= Tff7b72False
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.25Tb4b4b4)

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffi2pTff7b72.Td2a8ffreadyTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffI2P controller did not become available in time, waiting for controllerTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Te6edf3i2p_notready_warning Tff7b72= Tff7b72True

Tff7b72while Tff7b72not Tff7b72selfTff7b72.Td2a8ffi2pTff7b72.Td2a8ffreadyTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.25Tb4b4b4)

Tff7b72if Te6edf3i2p_notready_warning Tff7b72== Tff7b72TrueTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffI2P controller ready, continuing setupTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Tff7b72def Td2a8ffhandlerFactoryTb4b4b4(Te6edf3callbackTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffcreateHandlerTb4b4b4(Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3keysTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3I2PInterfaceHandlerTb4b4b4(Te6edf3callbackTb4b4b4, Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3keysTb4b4b4)
Tff7b72return Te6edf3createHandler
Te6edf3ThreadingI2PServerTff7b72.Td2a8ffallow_reuse_address Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffserver Tff7b72= Te6edf3ThreadingI2PServerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffaddressTb4b4b4, Te6edf3handlerFactoryTb4b4b4(Tff7b72selfTff7b72.Td2a8ffincoming_connectionTb4b4b4)Tb4b4b4)

Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffserverTff7b72.Td2a8ffserve_foreverTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ffconnectableTb4b4b4:
Tff7b72def Td2a8fftunnel_jobTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72TrueTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffi2pTff7b72.Td2a8ffserver_tunnelTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff I2P control process experienced an error, requesting new tunnel...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffonline Tff7b72= Tff7b72False

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while while configuring Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCheck that I2P is installed and running, and that SAM is enabled. Retrying tunnel setup later.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff15Tb4b4b4)


Te6edf3thread Tff7b72= Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3tunnel_jobTb4b4b4)
Te6edf3threadTff7b72.Td2a8ffdaemon Tff7b72= Tff7b72True
Te6edf3threadTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3peers Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72for Te6edf3peer_addr Tff7b72in Te6edf3peersTb4b4b4:
Te6edf3interface_name Tff7b72= Tff7b72selfTff7b72.Td2a8ffnameTff7b72+Ta5d6ff"Ta5d6ff to Ta5d6ff"Tff7b72+Te6edf3peer_addr
Te6edf3peer_interface Tff7b72= Te6edf3I2PInterfacePeerTb4b4b4(Tff7b72selfTb4b4b4, Tff7b72selfTff7b72.Td2a8ffownerTb4b4b4, Te6edf3interface_nameTb4b4b4, Te6edf3peer_addrTb4b4b4)
Te6edf3peer_interfaceTff7b72.Td2a8ffOUT Tff7b72= Tff7b72True
Te6edf3peer_interfaceTff7b72.Td2a8ffIN Tff7b72= Tff7b72True
Te6edf3peer_interfaceTff7b72.Td2a8ffparent_interface Tff7b72= Tff7b72self
Te6edf3peer_interfaceTff7b72.Td2a8ffparent_count Tff7b72= Tff7b72False
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffadd_interfaceTb4b4b4(Te6edf3peer_interfaceTb4b4b4)

Tff7b72def Td2a8ffincoming_connectionTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3handlerTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAccepting incoming I2P connectionTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Te6edf3interface_name Tff7b72= Ta5d6ff"Ta5d6ffConnected peer on Ta5d6ff"Tff7b72+Tff7b72selfTff7b72.Td2a8ffname
Te6edf3spawned_interface Tff7b72= Te6edf3I2PInterfacePeerTb4b4b4(Tff7b72selfTb4b4b4, Tff7b72selfTff7b72.Td2a8ffownerTb4b4b4, Te6edf3interface_nameTb4b4b4, Te6edf3connected_socketTff7b72=Te6edf3handlerTff7b72.Td2a8ffrequestTb4b4b4)
Te6edf3spawned_interfaceTff7b72.Td2a8ffOUT Tff7b72= Tff7b72True
Te6edf3spawned_interfaceTff7b72.Td2a8ffIN Tff7b72= Tff7b72True

Te6edf3spawned_interfaceTff7b72.Td2a8ffingress_control Tff7b72= Tff7b72selfTff7b72.Td2a8ffingress_control
Te6edf3spawned_interfaceTff7b72.Td2a8ffic_max_held_announces Tff7b72= Tff7b72selfTff7b72.Td2a8ffic_max_held_announces
Te6edf3spawned_interfaceTff7b72.Td2a8ffic_burst_hold Tff7b72= Tff7b72selfTff7b72.Td2a8ffic_burst_hold
Te6edf3spawned_interfaceTff7b72.Td2a8ffic_burst_freq Tff7b72= Tff7b72selfTff7b72.Td2a8ffic_burst_freq
Te6edf3spawned_interfaceTff7b72.Td2a8ffic_burst_freq_new Tff7b72= Tff7b72selfTff7b72.Td2a8ffic_burst_freq_new
Te6edf3spawned_interfaceTff7b72.Td2a8ffic_new_time Tff7b72= Tff7b72selfTff7b72.Td2a8ffic_new_time
Te6edf3spawned_interfaceTff7b72.Td2a8ffic_burst_penalty Tff7b72= Tff7b72selfTff7b72.Td2a8ffic_burst_penalty
Te6edf3spawned_interfaceTff7b72.Td2a8ffic_held_release_interval Tff7b72= Tff7b72selfTff7b72.Td2a8ffic_held_release_interval

Te6edf3spawned_interfaceTff7b72.Td2a8ffegress_control Tff7b72= Tff7b72selfTff7b72.Td2a8ffegress_control
Te6edf3spawned_interfaceTff7b72.Td2a8ffec_pr_freq Tff7b72= Tff7b72selfTff7b72.Td2a8ffec_pr_freq
Te6edf3spawned_interfaceTff7b72.Td2a8ffic_pr_burst_freq_new Tff7b72= Tff7b72selfTff7b72.Td2a8ffic_pr_burst_freq_new
Te6edf3spawned_interfaceTff7b72.Td2a8ffic_pr_burst_freq Tff7b72= Tff7b72selfTff7b72.Td2a8ffic_pr_burst_freq
Te6edf3spawned_interfaceTff7b72.Td2a8ffparent_interface Tff7b72= Tff7b72self
Te6edf3spawned_interfaceTff7b72.Td2a8ffonline Tff7b72= Tff7b72True
Te6edf3spawned_interfaceTff7b72.Td2a8ffbitrate Tff7b72= Tff7b72selfTff7b72.Td2a8ffbitrate

Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_size Tff7b72= Tff7b72selfTff7b72.Td2a8ffifac_size
Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_netname Tff7b72= Tff7b72selfTff7b72.Td2a8ffifac_netname
Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_netkey Tff7b72= Tff7b72selfTff7b72.Td2a8ffifac_netkey
Tff7b72if Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_netname Tff7b72!= Tff7b72None Tff7b72or Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_netkey Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ifac_origin Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ff"
Tff7b72if Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_netname Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ifac_origin Tff7b72+Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_netnameTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_netkey Tff7b72!= Tff7b72NoneTb4b4b4:
Te6edf3ifac_origin Tff7b72+Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_netkeyTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3ifac_origin_hash Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3ifac_originTb4b4b4)
Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_key Tff7b72= Te6edf3RNSTff7b72.Td2a8ffCryptographyTff7b72.Td2a8ffhkdfTb4b4b4(
Te6edf3lengthTff7b72=T79c0ff64Tb4b4b4,
Te6edf3derive_fromTff7b72=Te6edf3ifac_origin_hashTb4b4b4,
Te6edf3saltTff7b72=Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffIFAC_SALTTb4b4b4,
Te6edf3contextTff7b72=Tff7b72None
Tb4b4b4)
Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffrom_bytesTb4b4b4(Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_keyTb4b4b4)
Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_signature Tff7b72= Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_identityTff7b72.Td2a8ffsignTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffull_hashTb4b4b4(Te6edf3spawned_interfaceTff7b72.Td2a8ffifac_keyTb4b4b4)Tb4b4b4)

Te6edf3spawned_interfaceTff7b72.Td2a8ffannounce_rate_target Tff7b72= Tff7b72selfTff7b72.Td2a8ffannounce_rate_target
Te6edf3spawned_interfaceTff7b72.Td2a8ffannounce_rate_grace Tff7b72= Tff7b72selfTff7b72.Td2a8ffannounce_rate_grace
Te6edf3spawned_interfaceTff7b72.Td2a8ffannounce_rate_penalty Tff7b72= Tff7b72selfTff7b72.Td2a8ffannounce_rate_penalty
Te6edf3spawned_interfaceTff7b72.Td2a8ffmode Tff7b72= Tff7b72selfTff7b72.Td2a8ffmode
Te6edf3spawned_interfaceTff7b72.Td2a8ffHW_MTU Tff7b72= Tff7b72selfTff7b72.Td2a8ffHW_MTU
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffSpawned new I2PInterface Peer: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3spawned_interfaceTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffadd_interfaceTb4b4b4(Te6edf3spawned_interfaceTb4b4b4)
Tff7b72while Te6edf3spawned_interface Tff7b72in Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTff7b72.Td2a8ffremoveTb4b4b4(Te6edf3spawned_interfaceTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffspawned_interfacesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3spawned_interfaceTb4b4b4)
Te6edf3spawned_interfaceTff7b72.Td2a8ffread_loopTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffprocess_outgoingTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3dataTb4b4b4)Tb4b4b4:
Tff7b72pass

Tff7b72def Td2a8ffreceived_announceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3from_spawnedTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3from_spawnedTb4b4b4: Tff7b72selfTff7b72.Td2a8ffia_freq_dequeTff7b72.Td2a8ffappendTb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffsent_announceTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3from_spawnedTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3from_spawnedTb4b4b4: Tff7b72selfTff7b72.Td2a8ffoa_freq_dequeTff7b72.Td2a8ffappendTb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffreceived_path_requestTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3from_spawnedTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3from_spawnedTb4b4b4: Tff7b72selfTff7b72.Td2a8ffip_freq_dequeTff7b72.Td2a8ffappendTb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffsent_path_requestTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3from_spawnedTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3from_spawnedTb4b4b4: Tff7b72selfTff7b72.Td2a8ffop_freq_dequeTff7b72.Td2a8ffappendTb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffdetachTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDetaching Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffi2pTff7b72.Td2a8ffstopTb4b4b4(Tb4b4b4)

Tff7b72def Tff7b72__str__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffI2PInterface[Ta5d6ff"Tff7b72+Tff7b72selfTff7b72.Td2a8ffnameTff7b72+Ta5d6ff"Ta5d6ff]Ta5d6ff"

Tff7b72class T56d364I2PInterfaceHandlerTb4b4b4(Te6edf3socketserverTff7b72.Td2a8ffBaseRequestHandlerTb4b4b4)Tb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3callbackTb4b4b4, Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3keysTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcallback Tff7b72= Te6edf3callback
Te6edf3socketserverTff7b72.Td2a8ffBaseRequestHandlerTff7b72.Td2a8ff__init__Tb4b4b4(Tff7b72selfTb4b4b4, Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3keysTb4b4b4)

Tff7b72def Td2a8ffhandleTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffcallbackTb4b4b4(Te6edf3handlerTff7b72=Tff7b72selfTb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────